﻿#region

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using VinhSon.Intranet.Bussiness;
using VinhSon.Intranet.Models;

#endregion

namespace VinhSon.Intranet.Controllers
{
    public class UserGroupController : BaseController
    {
        #region UserGroup

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult GetList(int start,
                                    int limit,
                                    string sort)
        {
            var query = UnitOfWork.UserGroupRepository.Select(c => c.Inactive == false)
                                  .Select(c => new
                                               {
                                                   c.Id,
                                                   c.Name,
                                                   c.Description,
                                               });
            return Content(FormatResult(query,
                                        c => c.OrderBy(v => v.Name),
                                        start,
                                        limit,
                                        sort,
                                        UserGroupModel.Sort),
                           "json");
        }

        public ActionResult Add()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Add(UserGroupModel model)
        {
            if (ModelState.IsValid)
            {
                UpdateResult result = new UpdateResult();
                UserGroup userGroup = model;
                if (UnitOfWork.UserGroupRepository.CheckInsertUserGroup(userGroup))
                {
                    userGroup.CreatedByUserId = GetUserId();
                    UnitOfWork.UserGroupRepository.Insert(userGroup);
                    UnitOfWork.Save();
                }
                return Json(Server.FormatResultToJson(result));
            }
            return Json(Server.FormatResultToJson(ModelState));
        }

        public ActionResult Edit(string id)
        {
            int guid;
            if (int.TryParse(id,
                            out guid))
            {
                UserGroup userGroup = UnitOfWork.UserGroupRepository.SelectbyId(guid);
                if (userGroup != null)
                {
                    UserGroupModel webUserModel = userGroup;
                    return View(webUserModel);
                }
            }
            return RedirectToAction("Index");
        }

        [ValidateInput(false)]
        [HttpPost]
        public ActionResult Edit(UserGroupModel model)
        {
            if (ModelState.IsValid)
            {
                UpdateResult result = new UpdateResult();
                UserGroup userGroup = UnitOfWork.UserGroupRepository.SelectbyId(model.Id);
                model.Update(userGroup);
                if (UnitOfWork.UserGroupRepository.CheckUpdateUserGroup(userGroup))
                {
                    UnitOfWork.UserGroupRepository.Update(userGroup);
                    UnitOfWork.Save();
                }
                return Json(Server.FormatResultToJson(result));
            }
            return Json(Server.FormatResultToJson(ModelState));
        }

        [HttpPost]
        public ActionResult Delete(string id)
        {
            UpdateResult result = new UpdateResult();
            if (id != null)
            {
                string[] s = id.Split(',');
                int guid;
                List<int> list = (from s1 in s
                                  where int.TryParse(s1,
                                                     out guid)
                                  select int.Parse(s1)).ToList();

                if (UnitOfWork.UserGroupRepository.CheckDeleteUserGroup(list))
                {
                    UnitOfWork.UserGroupRepository.Delete(list);
                    UnitOfWork.Save();
                }
                else
                {
                    result.State = 4;
                    result.KeyLanguage = UpdateResult.INFORMATION_IN_USED;
                }
            }
            else
            {
                result.State = 4;
                result.KeyLanguage = UpdateResult.INFORMATION_IN_USED;
            }
            return Json(Server.FormatResultToJson(result));
        }

        #endregion

        #region Permission

        public ActionResult GetUserGroupPermissionList(int id,
                                                       string sort)
        {
            var query = UnitOfWork.UserGroupRepository.Select(c => c.Id == id && c.Inactive == false)
                                  .SelectMany(c => c.Permissions)
                                  .Where(c => c.Inactive == false)
                                  .Select(c => new
                                               {
                                                   c.Id,
                                                   c.Name,
                                                   c.Description,
                                                   c.GroupName,
                                               });
            return Content(FormatResult(query,
                                        c => c.OrderBy(v => v.Name),
                                        0,
                                        0,
                                        sort,
                                        PermissionModel.Sort),
                           "json");
        }

        public ActionResult GetPermissions(int id)
        {
            ViewBag.Id = id;
            return View();
        }

        [HttpPost]
        public ActionResult PermissionInList(int id,
                                             string sort)
        {
            var query = UnitOfWork.UserGroupRepository.Select(c => c.Id == id && c.Inactive == false)
                                  .SelectMany(c => c.Permissions)
                                  .Where(c => c.Inactive == false)
                                  .Select(c => new
                                               {
                                                   c.Id,
                                                   c.Name,
                                                   c.GroupName,
                                               });
            return Content(FormatResult(query,
                                        c => c.OrderBy(v => v.GroupName),
                                        0,
                                        0,
                                        sort,
                                        PermissionModel.Sort),
                           "json");
        }

        [HttpPost]
        public ActionResult PermissionOutList(int id,
                                              string sort)
        {
            int userId = GetUserId();
            User user = UnitOfWork.UserRepository.Select(c => c.Id == userId && c.Inactive == false,
                                                         "Roles.Permissions,UserGroups.Permissions")
                                  .FirstOrDefault();
            if (user != null)
            {
                UserGroup userGroup = UnitOfWork.UserGroupRepository.Select(c => c.Id == id && c.Inactive == false,
                                                                            "Permissions")
                                                .FirstOrDefault();
                if (userGroup != null)
                {
                    IEnumerable<int> query1 = userGroup.Permissions.Where(c => c.Inactive == false)
                                                       .Select(c => c.Id);
                    List<Permission> q1 = user.Roles.SelectMany(c => c.Permissions)
                                              .Where(c => c.Inactive == false && !query1.Contains(c.Id))
                                              .ToList();
                    List<Permission> q2 = user.UserGroups.SelectMany(c => c.Permissions)
                                              .Where(c => c.Inactive == false && !query1.Contains(c.Id))
                                              .ToList();
                    IEnumerable<Permission> q3 = q1.Union(q2)
                                                   .Distinct();
                    var query2 = q3.Where(c => !query1.Contains(c.Id))
                                   .Select(c => new
                                                {
                                                    c.Id,
                                                    c.Name,
                                                    c.GroupName,
                                                });
                    return Content(FormatResult(query2.AsQueryable(),
                                                c => c.OrderBy(v => v.GroupName),
                                                0,
                                                0,
                                                sort,
                                                PermissionModel.Sort),
                                   "json");
                }
            }
            return Content("");
        }

        [HttpPost]
        public ActionResult AddPermission(string id,
                                          int rid)
        {
            UpdateResult result = new UpdateResult();

            int userId = GetUserId();
            User user = UnitOfWork.UserRepository.Select(c => c.Id == userId && c.Inactive == false,
                                                         "Roles.Permissions,UserGroups.Permissions")
                                  .FirstOrDefault();
            if (user != null)
            {
                UserGroup userGroup = UnitOfWork.UserGroupRepository.Select(c => c.Id == rid && c.Inactive == false,
                                                                            "Permissions")
                                                .FirstOrDefault();
                if (userGroup != null)
                    if (!string.IsNullOrEmpty(id))
                    {
                        string[] s = id.Split(',');
                        List<int> list = new List<int>();
                        Array.ForEach(s,
                                      c =>
                                      {
                                          int i;
                                          if (int.TryParse(c,
                                                          out i))
                                              list.Add(i);
                                      });
                        List<Permission> q1 = user.Roles.SelectMany(c => c.Permissions)
                                                  .Where(c => c.Inactive == false && list.Contains(c.Id))
                                                  .ToList();
                        List<Permission> q2 = user.UserGroups.SelectMany(c => c.Permissions)
                                                  .Where(c => c.Inactive == false && list.Contains(c.Id))
                                                  .ToList();
                        IEnumerable<Permission> q3 = q1.Union(q2)
                                                       .Distinct();
                        foreach (Permission permission in q3)
                        {
                            if (!userGroup.Permissions.Contains(permission))
                                userGroup.Permissions.Add(permission);
                        }
                        UnitOfWork.Save();
                    }
            }

            return Json(Server.FormatResultToJson(result));
        }

        [HttpPost]
        public ActionResult RemovePermission(string id,
                                             int rid)
        {
            UpdateResult result = new UpdateResult();
            UserGroup userGroup = UnitOfWork.UserGroupRepository.Select(c => c.Id == rid && c.Inactive == false,
                                                                        "Permissions")
                                            .SingleOrDefault();
            if (userGroup != null)
            {
                string[] s = id.Split(',');
                List<int> list = new List<int>();
                Array.ForEach(s,
                              c =>
                              {
                                  int i;
                                  if (int.TryParse(c,
                                                  out i))
                                      list.Add(i);
                              });
                foreach (int i in list)
                {
                    Permission permission = userGroup.Permissions.FirstOrDefault(c => c.Id == i);
                    if (permission != null)
                        userGroup.Permissions.Remove(permission);
                }
                UnitOfWork.Save();
            }
            return Json(Server.FormatResultToJson(result));
        }

        #endregion

        #region User

        public ActionResult GetUserGroupUserList(int id,
                                                 int start,
                                                 int limit,
                                                 string sort)
        {
            var query = UnitOfWork.UserGroupRepository.Select(c => c.Id == id && c.Inactive == false)
                                  .SelectMany(c => c.Users)
                                  .Where(c => c.Inactive == false)
                                  .Select(c => new
                                               {
                                                   c.Id,
                                                   c.Username,
                                                   c.CreatedDate,
                                                   c.LastLoginDate,
                                                   c.Remark,
                                                   c.IsActivated,
                                                   c.IsLockedOut,
                                               });
            return Content(FormatResult(query,
                                        c => c.OrderBy(v => v.Username),
                                        start,
                                        limit,
                                        sort,
                                        UserModel.Sort,
                                        c => c.Select(v => new
                                                           {
                                                               v.Id,
                                                               v.Username,
                                                               CreatedDate = v.CreatedDate == null
                                                                                     ? null
                                                                                     : new DateTime?(v.CreatedDate.Value.ToUniversalTime()),
                                                               LastLoginDate = v.LastLoginDate == null
                                                                                       ? null
                                                                                       : new DateTime?(v.LastLoginDate.Value.ToUniversalTime()),
                                                               v.Remark,
                                                               v.IsActivated,
                                                               v.IsLockedOut
                                                           })),
                           "json");
        }

        public ActionResult GetUsers(int id)
        {
            ViewBag.Id = id;
            return View();
        }

        [HttpPost]
        public ActionResult UserGroupUserOutList(int id,
                                                 string sort)
        {
            List<int> query = UnitOfWork.UserGroupRepository.Select(c => c.Id == id && c.Inactive == false)
                                        .SelectMany(c => c.Users)
                                        .Where(c => c.Inactive == false)
                                        .Select(c => c.Id)
                                        .ToList();
            var q1 = UnitOfWork.UserRepository.Select(c => c.Inactive == false && !query.Contains(c.Id))
                               .Select(c => new
                                            {
                                                c.Id,
                                                c.Username,
                                            });
            return Content(FormatResult(q1,
                                        c => c.OrderBy(v => v.Username),
                                        0,
                                        0,
                                        sort,
                                        UserModel.Sort),
                           "json");
        }

        [HttpPost]
        public ActionResult UserGroupUserInList(int id,
                                                string sort)
        {
            var query = UnitOfWork.UserGroupRepository.Select(c => c.Id == id && c.Inactive == false)
                                  .SelectMany(c => c.Users)
                                  .Where(c => c.Inactive == false)
                                  .Select(c => new
                                               {
                                                   c.Id,
                                                   c.Username,
                                               });
            return Content(FormatResult(query,
                                        c => c.OrderBy(v => v.Username),
                                        0,
                                        0,
                                        sort,
                                        UserModel.Sort),
                           "json");
        }

        [HttpPost]
        public ActionResult AddUserGroupUser(int rid,
                                             string id)
        {
            UpdateResult result = new UpdateResult();

            if (!string.IsNullOrEmpty(id))
            {
                UserGroup userGroup = UnitOfWork.UserGroupRepository.Select(c => c.Id == rid && c.Inactive == false,
                                                                            "Users")
                                                .FirstOrDefault();
                if (userGroup != null)
                {
                    string[] s = id.Split(',');
                    List<int> list = new List<int>();
                    Array.ForEach(s,
                                  c =>
                                  {
                                      int i;
                                      if (int.TryParse(c,
                                                      out i))
                                          list.Add(i);
                                  });
                    IQueryable<User> q1 = UnitOfWork.UserRepository.Select(c => c.Inactive == false && list.Contains(c.Id));
                    foreach (User user in q1)
                    {
                        if (!userGroup.Users.Contains(user))
                            userGroup.Users.Add(user);
                    }
                    UnitOfWork.Save();
                }
            }

            return Json(Server.FormatResultToJson(result));
        }

        [HttpPost]
        public ActionResult RemoveUserGroupUser(int rid,
                                                string id)
        {
            UpdateResult result = new UpdateResult();

            if (!string.IsNullOrEmpty(id))
            {
                UserGroup userGroup = UnitOfWork.UserGroupRepository.Select(c => c.Id == rid && c.Inactive == false,
                                                                            "Users")
                                                .FirstOrDefault();
                if (userGroup != null)
                {
                    string[] s = id.Split(',');
                    List<int> list = new List<int>();
                    Array.ForEach(s,
                                  c =>
                                  {
                                      int i;
                                      if (int.TryParse(c,
                                                      out i))
                                          list.Add(i);
                                  });
                    foreach (int i in list)
                    {
                        User tmp = userGroup.Users.FirstOrDefault(c => c.Id == i);
                        if (tmp != null)
                            userGroup.Users.Remove(tmp);
                    }
                    UnitOfWork.Save();
                }
            }

            return Json(Server.FormatResultToJson(result));
        }

        #endregion
    }
}
